import {ExecutionContext, HttpException, HttpStatus, Injectable, NestInterceptor} from '@nestjs/common';
import {Observable, of} from 'rxjs';
import {AuthService} from './auth.service';
import {UnlimitedList} from "@/conf/authConf";
import {CacheTokenService} from "@/modules/cache/service/cacheTokenService";
import {classTransformerUtils} from "@/utils/classTransformerUtils";
import {User} from "@/entitys/base/user.entity";
import {HttpExceptionUtils} from "@/utils/httpExceptionUtils";


@Injectable()
export class GlobalGuard implements NestInterceptor {
    constructor(
        private authService: AuthService,
        private readonly CacheTokenService: CacheTokenService,
    ) {

    }

    async intercept(context: ExecutionContext, next: any): Promise<Observable<any>> {

        // 在这里执行全局守卫逻辑
        const request = context.switchToHttp().getRequest();
        // 从请求头中获取 token

        const url = request._parsedUrl.pathname;

        const open = UnlimitedList.includes(url);

        if (open) {
            return next.handle();
        }

        const tokenId = request.headers['token'];

        // todo
        if (!tokenId) {
            return HttpExceptionUtils.UNAUTHORIZED(next);
        }

        const getCacheTokenResult = await this.CacheTokenService.getCacheToken(tokenId);

        // todo
        if (getCacheTokenResult.err) {
            return HttpExceptionUtils.UNAUTHORIZED(next);
        }

        const access_token = getCacheTokenResult.data;

        if (!access_token) {
            return HttpExceptionUtils.UNAUTHORIZED(next);
        }


        const validRes = this.authService.validateToken(access_token);

        // todo
        if (!validRes) {
            return HttpExceptionUtils.UNAUTHORIZED(next);
        }


        // 添加用户信息到全局
        request.user = classTransformerUtils.plainToClass(User, this.authService.decodeToken(access_token));

        return next.handle();
    }
}
